package com.keithpower.freshdox;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * First bash of DefaultTestExtractor
 * Uses XML PArser, so very strict.
 * Will redo with ANTLR if I figure it out
 * @author Keith Power
 */
public class DefaultTestExtracter implements TestExtracter
{
    private static final String TEST_TAG = "freshdox:test";
    private static final String TEST_NAME_TAG = "name";
    private static final String TEST_LANGUAGE_TAG = "language";
    private static final String CONFIG_TAG = "freshdox:config";
    private static final String CONFIG_NAME_TAG = "name";
    private static final String CODE_TAG = "freshdox:code";
    private static final String CONDITION_TAG = "freshdox:condition";
    
    public Test[] extractTests(InputStream stream)
    {
        // Setup 
        DocumentBuilderFactory dbf =
            DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setValidating(false);
        Document doc=null;
        try
        {
            DocumentBuilder db = dbf.newDocumentBuilder();   
            doc = db.parse(stream);
        }catch (Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
                
        NodeList tests = doc.getElementsByTagName(TEST_TAG);
        Test [] parsedTests = new Test[tests.getLength()];                      
        
        for (int i = 0; i < tests.getLength(); i++)            
        {
            parsedTests[i] = new Test();
            
            // Get node name from tag
            Node testNode = tests.item(i);
            NamedNodeMap testNodeAttrs = testNode.getAttributes();
            String testName = (String) testNodeAttrs.getNamedItem(TEST_NAME_TAG).getNodeValue();
            parsedTests[i].setName(testName);
            if(testNodeAttrs.getNamedItem(TEST_LANGUAGE_TAG)!=null)
            {
                String testLang = (String) testNodeAttrs.getNamedItem(TEST_LANGUAGE_TAG).getNodeValue();
                parsedTests[i].setLanguage(testLang);
            }
            
            
            if(testNode.getNodeType()==Node.ELEMENT_NODE)
            {
//                System.out.println("Got a nodeTest element "+testName);
                Element testElem = (Element)testNode;
                
                String configsStr="", codeStr="", checkStr="";

                NodeList codes = testElem.getElementsByTagName(CODE_TAG);
                if(codes.getLength()>=1)
                {
                    Node codeNode = codes.item(0);
                    codeStr = codeNode.getTextContent();
//                    System.out.println("CODE: "+codeStr);
                    parsedTests[i].setCode(codeStr);
                }
   
                NodeList checks = testElem.getElementsByTagName(CONDITION_TAG);
                if(checks.getLength()>=1)
                {
                    Node checkNode = checks.item(0);
                    checkStr = checkNode.getTextContent();
                    parsedTests[i].setConditionCode(checkStr);
//                    System.out.println("COND: "+checkStr);
                }

                NodeList configs = testElem.getElementsByTagName(CONFIG_TAG);
                if(configs.getLength()>=1)
                {
                    for (int j = 0; j < configs.getLength(); j++)
                    {
                        Node configsNode = configs.item(0);
                        configsStr = configsNode.getTextContent();
//                        System.out.println("CONF: "+configsStr);
                        
                        NamedNodeMap configsNodeAttrs = configsNode.getAttributes();
                        String propName = (String) configsNodeAttrs.getNamedItem(CONFIG_NAME_TAG).getNodeValue();
//                        System.out.println("CONF: "+propName);
                        parsedTests[i].addConfig(propName, configsStr);

                    }
                }
            }
        }
                
        return parsedTests;
    }

}
